const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const db = require('../config/database');
const { successResponse, errorResponse } = require('../utils/response');

/**
 * 用户注册
 */
const register = async (req, res) => {
    try {
        const { username, password, school, grade, avatar } = req.body;
        
        // 验证必填字段
        if (!username || !password || !school || !grade) {
            return errorResponse(res, '请填写所有必填字段', 400);
        }
        
        // 检查用户名是否已存在
        const [existingUsers] = await db.execute(
            'SELECT id FROM users WHERE username = ?',
            [username]
        );
        
        if (existingUsers.length > 0) {
            return errorResponse(res, '用户名已存在', 400);
        }
        
        // 加密密码
        const hashedPassword = await bcrypt.hash(password, 10);
        
        // 插入新用户
        const [result] = await db.execute(
            `INSERT INTO users (username, password, school, grade, avatar) 
             VALUES (?, ?, ?, ?, ?)`,
            [username, hashedPassword, school, grade, avatar || 'avatar1']
        );
        
        const userId = result.insertId;
        
        // 创建默认宠物（随机选择）
        const petTypes = ['dragon', 'fox', 'panda', 'rabbit', 'cat', 'dog', 'bear', 'penguin'];
        const randomPet = petTypes[Math.floor(Math.random() * petTypes.length)];
        
        await db.execute(
            `INSERT INTO pets (user_id, pet_type, pet_name, level, exp, hunger, happiness, health)
             VALUES (?, ?, ?, 1, 0, 100, 100, 100)`,
            [userId, randomPet, `小${randomPet}`]
        );
        
        // 生成JWT token
        const token = jwt.sign(
            { id: userId, username, grade },
            process.env.JWT_SECRET || 'fun_english_secret_key_2025_lycc_top',
            { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
        );
        
        return successResponse(res, {
            user: {
                id: userId,
                username,
                school,
                grade,
                avatar: avatar || 'avatar1'
            },
            token
        }, '注册成功');
        
    } catch (error) {
        console.error('注册错误:', error);
        return errorResponse(res, '注册失败，请稍后重试', 500, error);
    }
};

/**
 * 用户登录（支持普通用户和管理员）
 */
const login = async (req, res) => {
    try {
        const { username, password } = req.body;
        
        // 验证必填字段
        if (!username || !password) {
            return errorResponse(res, '请输入用户名和密码', 400);
        }
        
        // 先尝试从管理员表查询
        const [admins] = await db.execute(
            'SELECT * FROM admins WHERE username = ?',
            [username]
        );
        
        if (admins.length > 0) {
            // 这是管理员账户
            const admin = admins[0];
            
            // 验证密码
            const isPasswordValid = await bcrypt.compare(password, admin.password);
            
            if (!isPasswordValid) {
                return errorResponse(res, '用户名或密码错误', 401);
            }
            
            // 检查管理员状态
            if (admin.status !== 'active') {
                return errorResponse(res, '该管理员账户已被禁用', 403);
            }
            
            // 更新最后登录时间
            await db.execute(
                'UPDATE admins SET last_login = NOW() WHERE id = ?',
                [admin.id]
            );
            
            // 记录管理员登录日志
            await db.execute(
                'INSERT INTO admin_logs (admin_id, action, details) VALUES (?, ?, ?)',
                [admin.id, 'login', '管理员登录']
            );
            
            // 解析permissions字段（可能是JSON字符串）
            let permissions = admin.permissions;
            if (typeof permissions === 'string') {
                try {
                    permissions = JSON.parse(permissions);
                } catch (e) {
                    console.error('解析permissions失败:', e);
                    permissions = {};
                }
            }
            
            // 生成JWT token
            const token = jwt.sign(
                { 
                    id: admin.id, 
                    username: admin.username, 
                    role: admin.role,
                    isAdmin: true 
                },
                process.env.JWT_SECRET || 'fun_english_secret_key_2025_lycc_top',
                { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
            );
            
            return successResponse(res, {
                user: {
                    id: admin.id,
                    username: admin.username,
                    role: admin.role,
                    real_name: admin.real_name,
                    isAdmin: true,
                    permissions: permissions
                },
                token
            }, '管理员登录成功');
        }
        
        // 查询普通用户
        const [users] = await db.execute(
            'SELECT * FROM users WHERE username = ?',
            [username]
        );
        
        if (users.length === 0) {
            return errorResponse(res, '用户名或密码错误', 401);
        }
        
        const user = users[0];
        
        // 验证密码
        const isPasswordValid = await bcrypt.compare(password, user.password);
        
        if (!isPasswordValid) {
            return errorResponse(res, '用户名或密码错误', 401);
        }
        
        // 更新最后登录时间和连续登录天数
        const today = new Date().toISOString().split('T')[0];
        const lastLogin = user.last_login ? new Date(user.last_login).toISOString().split('T')[0] : null;
        
        let continuousDays = user.continuous_days || 0;
        
        if (lastLogin) {
            const daysDiff = Math.floor((new Date(today) - new Date(lastLogin)) / (1000 * 60 * 60 * 24));
            if (daysDiff === 1) {
                // 连续登录
                continuousDays += 1;
            } else if (daysDiff > 1) {
                // 中断了，重新开始
                continuousDays = 1;
            }
            // daysDiff === 0 表示今天已经登录过，不变
        } else {
            continuousDays = 1;
        }
        
        await db.execute(
            'UPDATE users SET last_login = CURDATE(), continuous_days = ? WHERE id = ?',
            [continuousDays, user.id]
        );
        
        // 创建每日登录任务
        await db.execute(
            `INSERT IGNORE INTO daily_tasks (user_id, task_date, task_type, target_count, current_count, completed, stars_reward)
             VALUES (?, CURDATE(), 'login', 1, 1, TRUE, 5)`,
            [user.id]
        );
        
        // 如果完成登录任务，奖励星星
        await db.execute(
            `UPDATE users SET stars = stars + 5 
             WHERE id = ? 
             AND NOT EXISTS (
                 SELECT 1 FROM daily_tasks 
                 WHERE user_id = ? 
                 AND task_date = CURDATE() 
                 AND task_type = 'login' 
                 AND completed_at < NOW()
             )`,
            [user.id, user.id]
        );
        
        // 生成JWT token
        const token = jwt.sign(
            { id: user.id, username: user.username, grade: user.grade },
            process.env.JWT_SECRET || 'fun_english_secret_key_2025_lycc_top',
            { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
        );
        
        return successResponse(res, {
            user: {
                id: user.id,
                username: user.username,
                school: user.school,
                grade: user.grade,
                avatar: user.avatar,
                stars: user.stars + 5, // 登录奖励
                continuous_days: continuousDays,
                created_at: user.created_at,
                last_login: user.last_login,
                total_correct: user.total_correct,
                total_wrong: user.total_wrong
            },
            token
        }, '登录成功');
        
    } catch (error) {
        console.error('登录错误:', error);
        return errorResponse(res, '登录失败，请稍后重试', 500, error);
    }
};

/**
 * 获取用户信息
 */
const getUserInfo = async (req, res) => {
    try {
        const userId = req.user.id;
        
        const [users] = await db.execute(
            `SELECT id, username, school, grade, avatar, stars, 
                    total_correct, total_wrong, continuous_days, last_login, created_at
             FROM users WHERE id = ?`,
            [userId]
        );
        
        if (users.length === 0) {
            return errorResponse(res, '用户不存在', 404);
        }
        
        const user = users[0];
        
        // 获取宠物信息
        const [pets] = await db.execute(
            'SELECT * FROM pets WHERE user_id = ?',
            [userId]
        );
        
        // 获取学习进度统计
        const [progress] = await db.execute(
            `SELECT 
                COUNT(DISTINCT word_id) as words_learned,
                AVG(mastery_level) as avg_mastery
             FROM user_progress WHERE user_id = ?`,
            [userId]
        );
        
        // 获取成就数量
        const [achievements] = await db.execute(
            'SELECT COUNT(*) as count FROM user_achievements WHERE user_id = ?',
            [userId]
        );
        
        return successResponse(res, {
            ...user,
            pet: pets[0] || null,
            words_learned: progress[0].words_learned || 0,
            avg_mastery: Math.round(progress[0].avg_mastery || 0),
            achievements_count: achievements[0].count
        });
        
    } catch (error) {
        console.error('获取用户信息错误:', error);
        return errorResponse(res, '获取用户信息失败', 500, error);
    }
};

/**
 * 更新用户资料
 */
const updateProfile = async (req, res) => {
    try {
        const userId = req.user.id;
        const { school, grade, avatar } = req.body;
        
        // 构建更新字段
        const updates = [];
        const params = [];
        
        if (school !== undefined) {
            updates.push('school = ?');
            params.push(school);
        }
        
        if (grade !== undefined) {
            updates.push('grade = ?');
            params.push(grade);
        }
        
        if (avatar !== undefined) {
            updates.push('avatar = ?');
            params.push(avatar);
        }
        
        if (updates.length === 0) {
            return errorResponse(res, '没有要更新的字段', 400);
        }
        
        params.push(userId);
        
        const query = `UPDATE users SET ${updates.join(', ')} WHERE id = ?`;
        await db.execute(query, params);
        
        // 获取更新后的用户信息
        const [users] = await db.execute(
            'SELECT id, username, school, grade, avatar, stars, continuous_days FROM users WHERE id = ?',
            [userId]
        );
        
        return successResponse(res, users[0], '资料更新成功');
        
    } catch (error) {
        console.error('更新资料错误:', error);
        return errorResponse(res, '更新资料失败', 500, error);
    }
};

/**
 * 修改密码
 */
const changePassword = async (req, res) => {
    try {
        const userId = req.user.id;
        const { oldPassword, newPassword } = req.body;
        
        if (!oldPassword || !newPassword) {
            return errorResponse(res, '请提供旧密码和新密码', 400);
        }
        
        if (newPassword.length < 6) {
            return errorResponse(res, '新密码长度至少6位', 400);
        }
        
        // 获取用户当前密码
        const [users] = await db.execute(
            'SELECT password FROM users WHERE id = ?',
            [userId]
        );
        
        if (users.length === 0) {
            return errorResponse(res, '用户不存在', 404);
        }
        
        // 验证旧密码
        const isValidPassword = await bcrypt.compare(oldPassword, users[0].password);
        if (!isValidPassword) {
            return errorResponse(res, '旧密码不正确', 400);
        }
        
        // 加密新密码
        const hashedPassword = await bcrypt.hash(newPassword, 10);
        
        // 更新密码
        await db.execute(
            'UPDATE users SET password = ? WHERE id = ?',
            [hashedPassword, userId]
        );
        
        return successResponse(res, null, '密码修改成功');
        
    } catch (error) {
        console.error('修改密码错误:', error);
        return errorResponse(res, '修改密码失败', 500, error);
    }
};

module.exports = {
    register,
    login,
    getUserInfo,
    updateProfile,
    changePassword
};

